﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Activities;
using VMware.Vim;
using System.Collections.Specialized;

namespace VMWareActivities
{
    using Microsoft.TeamFoundation.Build.Client;

    [BuildActivity(HostEnvironmentOption.All)]
    public sealed class GetVMsActivity : CodeActivity
    {
        /// <summary>
        /// Gets or sets the name of the environment.
        /// </summary>
        /// <value>The name of the environment.</value>
        [RequiredArgument]
        public InArgument<string> EnvironmentName { get; set; }

        /// <summary>
        /// Gets or sets the VM ware connection.
        /// </summary>
        /// <value>The VM ware connection.</value>
        [RequiredArgument]
        public InArgument<VimClient> VMWareConnection { get; set; }

        /// <summary>
        /// Gets or sets the found virtual machines.
        /// </summary>
        /// <value>The found virtual machines.</value>
        [RequiredArgument]
        public OutArgument<VirtualMachine> FoundVM { get; set; }

        /// <summary>
        /// When implemented in a derived class, performs the execution of the activity.
        /// </summary>
        /// <param name="context">The execution context under which the activity executes.</param>
        protected override void Execute(CodeActivityContext context)
        {
            VimClient client = context.GetValue(this.VMWareConnection);
            string environmentName = context.GetValue(this.EnvironmentName);
            VirtualMachine foundVM = GetVM(client, environmentName);

            if (foundVM == null)
            {
                throw new Exception(string.Format("Virtual machine {0} not found!", environmentName));
            }

            context.SetValue(this.FoundVM, foundVM);
        }

        /// <summary>
        /// Gets the VM with the specified environment name.
        /// </summary>
        /// <param name="client">The client.</param>
        /// <param name="environmentName">Name of the environment.</param>
        /// <returns></returns>
        private static VirtualMachine GetVM(VimClient client, string environmentName)
        {
            // get all available VMs
            var filter = new NameValueCollection { { "Name", "" } };
            IList<EntityViewBase> vmList = client.FindEntityViews(typeof(VirtualMachine), null, filter, null);

            if (vmList == null)
            {
                return null;
            }
            
            foreach (VirtualMachine vm in vmList)
            {
                if (environmentName.Equals(vm.Config.Name))
                {
                    return vm;
                }
            }

            return null;
        }
    }
}
